$OpenBSD: patch-daemon_gdm-server_c,v 1.8 2016/04/15 14:11:09 ajacoutot Exp $

REVERT - OpenBSD lacks sigwaitinfo(2)
From 956d7d1c7a0cfbf2beacdb9e88e645e15ad32047 Mon Sep 17 00:00:00 2001
From: Jasper St. Pierre <jstpierre@mecheye.net>
Date: Fri, 14 Feb 2014 19:32:50 +0000
Subject: server: Process SIGUSR1 more carefully

REVERT - OpenBSD does not have a systemd implementation (we need ConsoleKit)
From 1ac67f522f5690c27023d98096ca817f12f7eb88 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 12 Jun 2015 13:28:01 -0400
Subject: drop consolekit support

REVERT - OpenBSD does not have a systemd implementation (we need ConsoleKit)
From 9be58c9ec9a3a411492a5182ac4b0d51fdc3a323 Mon Sep 17 00:00:00 2001
From: Ray Strode <rstrode@redhat.com>
Date: Fri, 12 Jun 2015 13:48:52 -0400
Subject: require logind support

--- daemon/gdm-server.c.orig	Thu Apr 14 07:29:22 2016
+++ daemon/gdm-server.c	Fri Apr 15 15:05:26 2016
@@ -43,7 +43,9 @@
 #include <linux/vt.h>
 #endif
 
+#ifdef WITH_SYSTEMD
 #include <systemd/sd-daemon.h>
+#endif
 
 #ifdef ENABLE_SYSTEMD_JOURNAL
 #include <systemd/sd-journal.h>
@@ -92,6 +94,7 @@ struct GdmServerPrivate
         char    *auth_file;
 
         guint    child_watch_id;
+        guint    sigusr1_id;
 
         gboolean is_initial;
 };
@@ -122,90 +125,76 @@ static void     gdm_server_finalize     (GObject      
 
 G_DEFINE_TYPE (GdmServer, gdm_server, G_TYPE_OBJECT)
 
-char *
-gdm_server_get_display_device (GdmServer *server)
+static char *
+_gdm_server_query_ck_for_display_device (GdmServer *server)
 {
-        /* systemd finds the display device out on its own based on the display */
-        return NULL;
-}
+        char    *out;
+        char    *command;
+        int      status;
+        gboolean res;
+        GError  *error;
 
-static void
-gdm_server_ready (GdmServer *server)
-{
-        g_debug ("GdmServer: Got USR1 from X server - emitting READY");
+        g_return_val_if_fail (GDM_IS_SERVER (server), NULL);
 
-        gdm_run_script (GDMCONFDIR "/Init", GDM_USERNAME,
-                        server->priv->display_name,
-                        NULL, /* hostname */
-                        server->priv->auth_file);
+        error = NULL;
+        command = g_strdup_printf (CONSOLEKIT_DIR "/ck-get-x11-display-device --display %s",
+                                   server->priv->display_name);
 
-        g_signal_emit (server, signals[READY], 0);
-}
-
-static GSList *active_servers;
-static gboolean sigusr1_thread_running;
-static GCond sigusr1_thread_cond;
-static GMutex sigusr1_thread_mutex;
-
-static gboolean
-got_sigusr1 (gpointer user_data)
-{
-        GPid pid = GPOINTER_TO_UINT (user_data);
-        GSList *l;
-
-        g_debug ("GdmServer: got SIGUSR1 from PID %d", pid);
-
-        for (l = active_servers; l; l = l->next) {
-                GdmServer *server = l->data;
-
-                if (server->priv->pid == pid)
-                        gdm_server_ready (server);
+        g_debug ("GdmServer: Running helper %s", command);
+        out = NULL;
+        res = g_spawn_command_line_sync (command,
+                                         &out,
+                                         NULL,
+                                         &status,
+                                         &error);
+        if (! res) {
+                g_warning ("Could not run helper: %s", error->message);
+                g_error_free (error);
+        } else {
+                out = g_strstrip (out);
+                g_debug ("GdmServer: Got tty: '%s'", out);
         }
 
-        return G_SOURCE_REMOVE;
+        g_free (command);
+
+        return out;
 }
 
-static gpointer
-sigusr1_thread_main (gpointer user_data)
+char *
+gdm_server_get_display_device (GdmServer *server)
 {
-        sigset_t sigusr1_mask;
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING()) {
+                /* systemd finds the display device out on its own based on the display */
+                return NULL;
+        }
+#endif
 
-        /* Handle only SIGUSR1 */
-        sigemptyset (&sigusr1_mask);
-        sigaddset (&sigusr1_mask, SIGUSR1);
-        sigprocmask (SIG_SETMASK, &sigusr1_mask, NULL);
+        if (server->priv->display_device == NULL) {
+                server->priv->display_device =
+                    _gdm_server_query_ck_for_display_device (server);
 
-        g_mutex_lock (&sigusr1_thread_mutex);
-        sigusr1_thread_running = TRUE;
-        g_cond_signal (&sigusr1_thread_cond);
-        g_mutex_unlock (&sigusr1_thread_mutex);
-
-        /* Spin waiting for a SIGUSR1 */
-        while (TRUE) {
-                siginfo_t info;
-
-                if (sigwaitinfo (&sigusr1_mask, &info) == -1)
-                        continue;
-
-                g_idle_add (got_sigusr1, GUINT_TO_POINTER (info.si_pid));
+                g_object_notify (G_OBJECT (server), "display-device");
         }
 
-        return NULL;
+        return g_strdup (server->priv->display_device);
 }
 
-static void
-gdm_server_launch_sigusr1_thread_if_needed (void)
+static gboolean
+on_sigusr1 (gpointer user_data)
+
 {
-        static GThread *sigusr1_thread;
+        GdmServer *server = user_data;
 
-        if (sigusr1_thread == NULL) {
-                sigusr1_thread = g_thread_new ("gdm SIGUSR1 catcher", sigusr1_thread_main, NULL);
+        g_debug ("GdmServer: Got USR1 from X server - emitting READY");
 
-                g_mutex_lock (&sigusr1_thread_mutex);
-                while (!sigusr1_thread_running)
-                        g_cond_wait (&sigusr1_thread_cond, &sigusr1_thread_mutex);
-                g_mutex_unlock (&sigusr1_thread_mutex);
-        }
+        gdm_run_script (GDMCONFDIR "/Init", GDM_USERNAME,
+                        server->priv->display_name,
+                        NULL, /* hostname */
+                        server->priv->auth_file);
+
+        g_signal_emit (server, signals[READY], 0);
+        return FALSE;
 }
 
 static void
@@ -226,8 +215,10 @@ gdm_server_init_command (GdmServer *server)
                 debug_options = "";
         }
 
-#define X_SERVER_ARG_FORMAT " -background none -noreset -verbose %s%s"
+        #define X_SERVER_ARG_FORMAT " -background none -noreset -verbose %s%s"
 
+#ifdef WITH_SYSTEMD
+
         /* This is a temporary hack to work around the fact that XOrg
          * currently lacks support for multi-seat hotplugging for
          * display devices. This bit should be removed as soon as XOrg
@@ -242,6 +233,10 @@ gdm_server_init_command (GdmServer *server)
          * wasn't booted using systemd, or b) the wrapper tool is
          * missing, or c) we are running for the main seat 'seat0'. */
 
+        if (!LOGIND_RUNNING()) {
+                goto fallback;
+        }
+
 #ifdef ENABLE_SYSTEMD_JOURNAL
         /* For systemd, we don't have a log file but instead log to stdout,
            so set it to the xserver's built-in default verbosity */
@@ -264,8 +259,9 @@ gdm_server_init_command (GdmServer *server)
         return;
 
 fallback:
-        server->priv->command = g_strdup_printf (X_SERVER X_SERVER_ARG_FORMAT, verbosity, debug_options);
+#endif
 
+        server->priv->command = g_strdup_printf (X_SERVER X_SERVER_ARG_FORMAT, verbosity, debug_options);
 }
 
 static gboolean
@@ -315,10 +311,12 @@ gdm_server_resolve_command_line (GdmServer  *server,
                 argv[len++] = g_strdup (server->priv->auth_file);
         }
 
-        if (server->priv->display_seat_id != NULL) {
+#ifdef WITH_SYSTEMD
+        if (LOGIND_RUNNING() && server->priv->display_seat_id != NULL) {
                 argv[len++] = g_strdup ("-seat");
                 argv[len++] = g_strdup (server->priv->display_seat_id);
         }
+#endif
 
         /* If we were compiled with Xserver >= 1.17 we need to specify
          * '-listen tcp' as the X server dosen't listen on tcp sockets
@@ -663,12 +661,6 @@ server_child_watch (GPid       pid,
         g_object_unref (server);
 }
 
-static void
-prune_active_servers_list (GdmServer *server)
-{
-        active_servers = g_slist_remove (active_servers, server);
-}
-
 static gboolean
 gdm_server_spawn (GdmServer    *server,
                   const char   *vtarg,
@@ -706,15 +698,6 @@ gdm_server_spawn (GdmServer    *server,
         g_debug ("GdmServer: Starting X server process: %s", freeme);
         g_free (freeme);
 
-        active_servers = g_slist_append (active_servers, server);
-
-        g_object_weak_ref (G_OBJECT (server),
-                           (GWeakNotify)
-                           prune_active_servers_list,
-                           server);
-
-        gdm_server_launch_sigusr1_thread_if_needed ();
-
         if (!g_spawn_async_with_pipes (NULL,
                                        argv,
                                        (char **)env->pdata,
@@ -1050,11 +1033,16 @@ gdm_server_class_init (GdmServerClass *klass)
 static void
 gdm_server_init (GdmServer *server)
 {
+
         server->priv = GDM_SERVER_GET_PRIVATE (server);
 
         server->priv->pid = -1;
 
         server->priv->log_dir = g_strdup (LOGDIR);
+
+        server->priv->sigusr1_id = g_unix_signal_add (SIGUSR1,
+                                                      on_sigusr1,
+                                                      server);
 }
 
 static void
@@ -1068,6 +1056,9 @@ gdm_server_finalize (GObject *object)
         server = GDM_SERVER (object);
 
         g_return_if_fail (server->priv != NULL);
+
+        if (server->priv->sigusr1_id > 0)
+                g_source_remove (server->priv->sigusr1_id);
 
         gdm_server_stop (server);
 
